import numpy as np
import matplotlib.pyplot as plt
import torch
import torch.nn as nn

#
# # data = np.arange(100, 201)
# # # plt.plot(data)
# # # plt.show()
# #
# x = np.linspace(2 * np.pi, 2 * np.pi, 200)
# y = np.cos(x)
#
# # # plt.plot(x, y)
# # # plt.show()
# # x = torch.linspace(-7, 7, 200)
# # y = torch.sin(x)
# # # plt.plot(x, y)
# # # plt.show()
# # print(x.dtype)
# # print(x.shape)
# # # 1
# # # x = x.unsqueeze(1)
# # # 2
# x = x.reshape([200, 1])
# y = y.reshape([200, 1])
# x = torch.from_numpy(x)
# # print(x.shape)
# # # view是？
# # x2 = x.view(200, 1)
# # print(x2.shape)
# # # xx = torch.from_numpy(data)
# # # print(type(xx))
# # # print(xx.shape)
# # #
# # # print(torch.Size(xx))
#
# # 加上nn.ReLU()存在了非线性
# net = nn.Sequential(
#     nn.Linear(1, 50), nn.ReLU(),
#     nn.Linear(50, 200), nn.ReLU(),
#     nn.Linear(200, 30), nn.ReLU(),
#     nn.Linear(30, 1)
# )
#
# # print(net)
# # 生成器
# # print(list(net.named_parameters()))
#
# # 帮助朝着正确方向前进
# loss_fun = nn.MSELoss()
# # 怎么前进 优化器
# optimizer = torch.optim.SGD(
#     net.parameters(),  # 数据
#     lr=0.01  # 跳跃步长?
# )
#
# for epoch in range(500):
#     y_predicted = net(x)  # 模型预测
#     optimizer.zero_grad()
#     loss = loss_fun(y_predicted, y)  # 预测与真实差值
#     loss.backward()  # 反向传播
#     optimizer.step()  # 更正
#     if (epoch + 1) % 100 == 0:
#         print(f'epoch:{epoch + 1}, train_loss:{loss.item():.6f}')
#
# plt.plot(x, net(x).detach(), r='red')
# plt.show()

x = np.linspace(0, 2 * np.pi, 200)
y = np.cos(x)

x = x.reshape([200, 1])
y = y.reshape([200, 1])
x = torch.from_numpy(x).float()
y = torch.from_numpy(y).float()

# 加上nn.ReLU()存在了非线性
net = nn.Sequential(
    nn.Linear(1, 50), nn.ReLU(),
    nn.Linear(50, 200), nn.ReLU(),
    nn.Linear(200, 30), nn.ReLU(),
    nn.Linear(30, 1)
)

# 帮助朝着正确方向前进
loss_fun = nn.MSELoss()
# 怎么前进 优化器
optimizer = torch.optim.SGD(
    net.parameters(),  # 数据
    lr=0.01  # 跳跃步长?
)

for epoch in range(5000):
    y_predicted = net(x)  # 模型预测
    optimizer.zero_grad()
    loss = loss_fun(y_predicted, y)  # 预测与真实差值
    loss.backward()  # 反向传播
    optimizer.step()  # 更正
    if (epoch + 1) % 100 == 0:
        print(f'epoch:{epoch + 1}, train_loss:{loss.item():.6f}')

plt.plot(x.numpy(), net(x).detach().numpy(), 'r')
plt.plot(x.numpy(), y.numpy(), 'b')
plt.show()